package com.example.system.information.log;

import android.content.Context;
import android.os.Build;
import android.os.Environment;
import android.util.Log;

import java.io.BufferedReader;
import java.io.File;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.List;
import java.util.Locale;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * 日志获取工具类
 * 提供从系统日志或应用私有日志文件获取不同类型日志的功能
 */
public class LogUtils {
    private static final String TAG = "LogUtils";
    private static LogUtils instance;
    private Context context;
    private SimpleDateFormat logcatDateFormat;

    // 私有构造函数
    private LogUtils(Context context) {
        this.context = context.getApplicationContext();
        // 根据Android版本设置不同的日志时间格式
        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
            // Android 7.0+ 日志格式: MM-dd HH:mm:ss.sss
            logcatDateFormat = new SimpleDateFormat("MM-dd HH:mm:ss.SSS", Locale.getDefault());
        } else {
            // Android 7.0- 日志格式: MM-dd HH:mm:ss.sss
            logcatDateFormat = new SimpleDateFormat("yyyy-MM-dd-HH:mm:ss.SSS", Locale.getDefault());
        }
    }

    // 获取单例实例
    public static synchronized LogUtils getInstance(Context context) {
        if (instance == null) {
            instance = new LogUtils(context);
        }
        return instance;
    }

    /**
     * 获取指定类型的日志
     *
     * @param logType   日志类型，如"error", "network", "performance"等
     * @param startTime 开始时间戳(毫秒)
     * @param endTime   结束时间戳(毫秒)
     * @param maxCount  最大返回数量
     * @return 日志列表
     */
    public List<LogEntry> getLogs(String logType, long startTime, long endTime, int maxCount) {
        switch (logType.toLowerCase()) {
            case "error":
                return getErrorLogs(startTime, endTime, maxCount);
            case "network":
                return getNetworkLogs(startTime, endTime, maxCount);
            case "performance":
                return getPerformanceLogs(startTime, endTime, maxCount);
            case "ui":
                return getUILogs(startTime, endTime, maxCount);
            case "database":
                return getDatabaseLogs(startTime, endTime, maxCount);
            case "security":
                return getSecurityLogs(startTime, endTime, maxCount);
            default:
                Log.w(TAG, "Unsupported log type: " + logType);
                return new ArrayList<>();
        }
    }

    // ------------------------ 系统日志获取方法 ------------------------

    /**
     * 获取错误日志（从系统日志）
     */
    private List<LogEntry> getErrorLogs(long startTime, long endTime, int maxCount) {
        List<LogEntry> logs = new ArrayList<>();
        Process process = null;
        BufferedReader bufferedReader = null;

        try {
            // 执行logcat命令过滤错误日志
            process = Runtime.getRuntime().exec("logcat -d *:E");
            bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

            // 适配不同Android版本的日志格式
            Pattern pattern;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                // Android 7.0+ 日志格式: MM-dd HH:mm:ss.sss PID-TID LEVEL/TAG: message
                pattern = Pattern.compile("(\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d{3}) (.*)");
            } else {
                // Android 7.0- 日志格式: yyyy-MM-dd-HH:mm:ss.SSS PID-TID LEVEL/TAG: message
                pattern = Pattern.compile("(\\d{4}-\\d{2}-\\d{2}-\\d{2}:\\d{2}:\\d{2}.\\d{3}) (.*)");
            }

            String line;
            int count = 0;

            while ((line = bufferedReader.readLine()) != null && count < maxCount) {
                Matcher matcher = pattern.matcher(line);
                if (matcher.find()) {
                    String dateStr = matcher.group(1);
                    String message = matcher.group(2);

                    // 将日志时间转换为时间戳
                    long logTime = parseLogTime(dateStr);

                    // 检查日志时间是否在范围内
                    if (logTime >= startTime && logTime <= endTime) {
                        logs.add(new LogEntry(logTime, "error", message));
                        count++;
                    }
                }
            }
        } catch (IOException e) {
            Log.e(TAG, "Error reading error logs", e);
        } finally {
            // 关闭资源
            closeResources(bufferedReader, process);
        }

        return logs;
    }

    /**
     * 获取网络日志（从系统日志）
     */
    private List<LogEntry> getNetworkLogs(long startTime, long endTime, int maxCount) {
        List<LogEntry> logs = new ArrayList<>();
        Process process = null;
        BufferedReader bufferedReader = null;

        try {
            // 执行logcat命令过滤网络相关日志
            // 扩展过滤条件，覆盖更多网络相关日志
            String command = "logcat -d NetworkSecurityConfig:V OkHttp:D DalvikNetwork:D ConnectivityManager:V *:S";
            process = Runtime.getRuntime().exec(command);
            bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

            // 适配不同Android版本的日志格式
            Pattern pattern;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                pattern = Pattern.compile("(\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d{3}) (.*)");
            } else {
                pattern = Pattern.compile("(\\d{4}-\\d{2}-\\d{2}-\\d{2}:\\d{2}:\\d{2}.\\d{3}) (.*)");
            }

            String line;
            int count = 0;

            while ((line = bufferedReader.readLine()) != null && count < maxCount) {
                Matcher matcher = pattern.matcher(line);
                if (matcher.find()) {
                    String dateStr = matcher.group(1);
                    String message = matcher.group(2);

                    // 将日志时间转换为时间戳
                    long logTime = parseLogTime(dateStr);

                    // 检查日志时间是否在范围内
                    if (logTime >= startTime && logTime <= endTime) {
                        logs.add(new LogEntry(logTime, "network", message));
                        count++;
                    }
                }
            }
        } catch (IOException e) {
            Log.e(TAG, "Error reading network logs", e);
        } finally {
            // 关闭资源
            closeResources(bufferedReader, process);
        }

        return logs;
    }

    /**
     * 获取性能日志（从系统日志）
     */
    private List<LogEntry> getPerformanceLogs(long startTime, long endTime, int maxCount) {
        List<LogEntry> logs = new ArrayList<>();
        Process process = null;
        BufferedReader bufferedReader = null;

        try {
            // 执行logcat命令过滤性能相关日志
            String command;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.Q) {
                // Android 10+ 使用更广泛的性能日志过滤
                command = "logcat -d Perf:V Choreographer:V SurfaceFlinger:V *:S";
            } else if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                // Android 7.0-9.0
                command = "logcat -d dalvikvm:V art:V ActivityManager:V *:S";
            } else {
                // 旧版本使用 Dalvik/ART 性能日志
                command = "logcat -d dalvikvm:V art:V *:S";
            }

            process = Runtime.getRuntime().exec(command);
            bufferedReader = new BufferedReader(new InputStreamReader(process.getInputStream()));

            // 适配不同Android版本的日志格式
            Pattern pattern;
            if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.N) {
                pattern = Pattern.compile("(\\d{2}-\\d{2} \\d{2}:\\d{2}:\\d{2}.\\d{3}) (.*)");
            } else {
                pattern = Pattern.compile("(\\d{4}-\\d{2}-\\d{2}-\\d{2}:\\d{2}:\\d{2}.\\d{3}) (.*)");
            }

            String line;
            int count = 0;

            while ((line = bufferedReader.readLine()) != null && count < maxCount) {
                Matcher matcher = pattern.matcher(line);
                if (matcher.find()) {
                    String dateStr = matcher.group(1);
                    String message = matcher.group(2);

                    // 将日志时间转换为时间戳
                    long logTime = parseLogTime(dateStr);

                    // 检查日志时间是否在范围内
                    if (logTime >= startTime && logTime <= endTime) {
                        logs.add(new LogEntry(logTime, "performance", message));
                        count++;
                    }
                }
            }
        } catch (IOException e) {
            Log.e(TAG, "Error reading performance logs", e);
        } finally {
            // 关闭资源
            closeResources(bufferedReader, process);
        }

        return logs;
    }

    // ------------------------ 文件日志获取方法 ------------------------

    /**
     * 获取UI日志（从文件）
     */
    private List<LogEntry> getUILogs(long startTime, long endTime, int maxCount) {
        List<LogEntry> logs = new ArrayList<>();
        File logFile = new File(context.getFilesDir(), "ui_logs.txt");

        if (!logFile.exists()) {
            return logs;
        }

        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(logFile));
            String line;
            int count = 0;

            while ((line = reader.readLine()) != null && count < maxCount) {
                // 假设日志格式为：时间戳|日志内容
                String[] parts = line.split("\\|", 2);
                if (parts.length == 2) {
                    try {
                        long logTime = Long.parseLong(parts[0]);
                        if (logTime >= startTime && logTime <= endTime) {
                            logs.add(new LogEntry(logTime, "ui", parts[1]));
                            count++;
                        }
                    } catch (NumberFormatException e) {
                        Log.e(TAG, "Invalid log time format", e);
                    }
                }
            }
        } catch (IOException e) {
            Log.e(TAG, "Error reading UI logs", e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    Log.e(TAG, "Error closing file reader", e);
                }
            }
        }

        return logs;
    }

    /**
     * 获取数据库日志（从文件）
     */
    private List<LogEntry> getDatabaseLogs(long startTime, long endTime, int maxCount) {
        List<LogEntry> logs = new ArrayList<>();
        File logFile = new File(context.getFilesDir(), "database_logs.txt");

        if (!logFile.exists()) {
            return logs;
        }

        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(logFile));
            String line;
            int count = 0;

            while ((line = reader.readLine()) != null && count < maxCount) {
                // 假设日志格式为：时间戳|操作类型|操作内容
                String[] parts = line.split("\\|", 3);
                if (parts.length == 3) {
                    try {
                        long logTime = Long.parseLong(parts[0]);
                        if (logTime >= startTime && logTime <= endTime) {
                            String message = "Operation: " + parts[1] + ", Details: " + parts[2];
                            logs.add(new LogEntry(logTime, "database", message));
                            count++;
                        }
                    } catch (NumberFormatException e) {
                        Log.e(TAG, "Invalid log time format", e);
                    }
                }
            }
        } catch (IOException e) {
            Log.e(TAG, "Error reading database logs", e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    Log.e(TAG, "Error closing file reader", e);
                }
            }
        }

        return logs;
    }

    /**
     * 获取安全日志（从文件）
     */
    private List<LogEntry> getSecurityLogs(long startTime, long endTime, int maxCount) {
        List<LogEntry> logs = new ArrayList<>();
        File logFile = new File(context.getFilesDir(), "security_logs.txt");

        if (!logFile.exists()) {
            return logs;
        }

        BufferedReader reader = null;
        try {
            reader = new BufferedReader(new FileReader(logFile));
            String line;
            int count = 0;

            while ((line = reader.readLine()) != null && count < maxCount) {
                // 假设日志格式为：时间戳|安全事件类型|事件详情
                String[] parts = line.split("\\|", 3);
                if (parts.length == 3) {
                    try {
                        long logTime = Long.parseLong(parts[0]);
                        if (logTime >= startTime && logTime <= endTime) {
                            String message = "Security Event: " + parts[1] + ", Details: " + parts[2];
                            logs.add(new LogEntry(logTime, "security", message));
                            count++;
                        }
                    } catch (NumberFormatException e) {
                        Log.e(TAG, "Invalid log time format", e);
                    }
                }
            }
        } catch (IOException e) {
            Log.e(TAG, "Error reading security logs", e);
        } finally {
            if (reader != null) {
                try {
                    reader.close();
                } catch (IOException e) {
                    Log.e(TAG, "Error closing file reader", e);
                }
            }
        }

        return logs;
    }


    // ------------------------ 辅助方法 ------------------------

    /**
     * 解析logcat时间戳为毫秒时间戳
     */
    private long parseLogTime(String logTimeStr) {
        try {
            // 使用适配的日期格式解析
            Date date = logcatDateFormat.parse(logTimeStr);

            // 由于logcat时间没有包含年份信息，需要补充年份
            Calendar calendar = Calendar.getInstance();
            int currentYear = calendar.get(Calendar.YEAR);
            calendar.setTime(date);
            calendar.set(Calendar.YEAR, currentYear);

            // 处理跨年问题（如果解析的日期比当前日期大超过360天，则年份减1）
            Date now = new Date();
            if (calendar.getTime().getTime() - now.getTime() > 360 * 24 * 60 * 60 * 1000) {
                calendar.add(Calendar.YEAR, -1);
            }

            return calendar.getTimeInMillis();
        } catch (ParseException e) {
            Log.e(TAG, "Error parsing log time: " + logTimeStr, e);
            // 解析失败返回当前时间
            return System.currentTimeMillis();
        }
    }

    /**
     * 关闭资源
     */
    private void closeResources(BufferedReader reader, Process process) {
        if (reader != null) {
            try {
                reader.close();
            } catch (IOException e) {
                Log.e(TAG, "Error closing reader", e);
            }
        }

        if (process != null) {
            process.destroy();
        }
    }
}